package com.axialproject.health.exchange.healthvaultppe;

import com.axialproject.health.exchange.EMF;
import com.axialproject.health.exchange.PatientManager;
import com.axialproject.health.exchange.entity.Patient;
import com.microsoft.hsg.ApplicationConfig;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class CreateLoginServlet extends HttpServlet {

    private static final Logger log = Logger.getLogger(CreateLoginServlet.class.getName());

    public void doGet (HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {

        String appUrl = this.getServletContext().getInitParameter("AppUrl");

        // Input parameters: appName, patientId
        String appName = req.getParameter ("appName");
        String username = req.getParameter ("username");
        // Redirect with loginUrl param after the loginUrl is generated
        String redirectUrl = req.getParameter ("redirectUrl");
        // Redirect after the entire process is finished after successful /confirm
        String finishUrl = req.getParameter ("finishUrl");
        if (finishUrl == null) {
            finishUrl = "";
        }

        HttpSession session = req.getSession ();
        // Need to use this when HV redirects to /after_login
        session.setAttribute ("finishUrl", finishUrl);

        Patient patient = null; // this is the patient we plan to connect
        Patient hvpatient = null; // this is the HV account for the patient
        EntityManager em = EMF.get().createEntityManager();
        try {
            patient = PatientManager.getPatientByUsernameAppName(em, username, appName);
            if (patient == null) {
                patient = new Patient ();
                patient.setUsername(username);
                patient.setAppName(appName);
                PatientManager.savePatient(em, patient);

            } else {
                List <Patient> patients = PatientManager.getLinkedPatients(em, patient.getId());
                if (patients == null) {
                    patients = new ArrayList <Patient> ();
                }
                for (Patient p : patients) {
                    if ("healthvaultppe".equals(p.getAppName()) && p.getUsername() != null && p.getToken() != null) {
                        boolean validToken = false;
                        // TODO: validate the token and username
                        validToken = true;
                        if (validToken) {
                            hvpatient = p;
                        }
                    }
                }
            }

        } catch (Exception e) {
            log.log(Level.SEVERE, e.getMessage(), e);
            resp.setContentType("text/plain");
            resp.getWriter().print("");
            return;
        } finally {
            em.close ();
        }

        if (hvpatient == null) {
            session.setAttribute ("patientId", patient.getId());

            // Show the link
            String nextUrl = appUrl + "/healthvaultppe/after_login";
            String loginUrl = createShellURL(nextUrl);

            if (redirectUrl != null && !"".equals(redirectUrl)) {
                if (redirectUrl.contains("?")) {
                    resp.sendRedirect(redirectUrl + "&loginUrl=" + URLEncoder.encode(loginUrl, "UTF-8"));
                } else {
                    resp.sendRedirect(redirectUrl + "?loginUrl=" + URLEncoder.encode(loginUrl, "UTF-8"));
                }
            } else {
                resp.setContentType("text/plain");
                resp.getWriter().print(loginUrl);
            }

        } else {
            // Already registered
            log.info("The username is already connected to MSHV");
            if (redirectUrl != null && !"".equals(redirectUrl)) {
                if (redirectUrl.contains("?")) {
                    resp.sendRedirect(redirectUrl + "&offlinePersonName=" + hvpatient.getName() + "&appName=" + URLEncoder.encode(appName, "UTF-8") + "&username=" + URLEncoder.encode(username, "UTF-8"));
                } else {
                    resp.sendRedirect(redirectUrl + "?offlinePersonName=" + hvpatient.getName() + "&appName=" + URLEncoder.encode(appName, "UTF-8") + "&username=" + URLEncoder.encode(username, "UTF-8"));
                }
            } else {
                resp.setContentType("text/plain");
                resp.getWriter().print("");
            }
        }

    }

    private String createShellURL (String nextUrl) {
        StringBuffer url = new StringBuffer();
        url.append(Config.ShellUrl);
        url.append("/redirect.aspx?target=AUTH&targetqs=?appid=");
        url.append(ApplicationConfig.APP_ID);
        url.append("%26redirect=" + nextUrl);

        if (Config.ActionQS != null && Config.ActionQS.trim().length()!=0) {
            url.append("%26actionqs=");
            url.append(Config.ActionQS);
        }
        return url.toString();
    }

    public void doPost (HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
        doGet (req, resp);
    }
}
